home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / dos / malloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-18  |  2.7 KB  |  115 lines

  1. /*
  2.  * malloc.c
  3.  *
  4.  * Very simple linked-list based malloc()/free().
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include "malloc.h"
  9.  
  10. struct free_arena_header __malloc_head =
  11. {
  12.   {
  13.     ARENA_TYPE_HEAD,
  14.     0,
  15.     &__malloc_head,
  16.     &__malloc_head,
  17.   },
  18.   &__malloc_head,
  19.   &__malloc_head
  20. };
  21.  
  22. /* This is extern so it can be overridden by the user application */
  23. const size_t __stack_size = 4096;
  24.  
  25. static inline size_t sp(void)
  26. {
  27.   uint32_t sp;
  28.   asm volatile("movl %%esp,%0" : "=rm" (sp));
  29.   return sp;
  30. }
  31.  
  32. extern void *__mem_end;
  33.  
  34. void __init_memory_arena(void)
  35. {
  36.   struct free_arena_header *fp;
  37.   size_t start, total_space;
  38.  
  39.   start = (size_t)ARENA_ALIGN_UP(__mem_end);
  40.   total_space = sp() - start;
  41.  
  42.   fp = (struct free_arena_header *)start;
  43.   fp->a.type = ARENA_TYPE_FREE;
  44.   fp->a.size = total_space - __stack_size;
  45.   
  46.   /* Insert into chains */
  47.   fp->a.next = fp->a.prev = &__malloc_head;
  48.   fp->next_free = fp->prev_free = &__malloc_head;
  49.   __malloc_head.a.next = __malloc_head.a.prev = fp;
  50.   __malloc_head.next_free = __malloc_head.prev_free = fp;
  51. }
  52.  
  53. static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
  54. {
  55.   size_t fsize;
  56.   struct free_arena_header *nfp, *na;
  57.  
  58.   fsize = fp->a.size;
  59.   
  60.   /* We need the 2* to account for the larger requirements of a free block */
  61.   if ( fsize >= size+2*sizeof(struct arena_header) ) {
  62.     /* Bigger block than required -- split block */
  63.     nfp = (struct free_arena_header *)((char *)fp + size);
  64.     na = fp->a.next;
  65.  
  66.     nfp->a.type = ARENA_TYPE_FREE;
  67.     nfp->a.size = fsize-size;
  68.     fp->a.type  = ARENA_TYPE_USED;
  69.     fp->a.size  = size;
  70.  
  71.     /* Insert into all-block chain */
  72.     nfp->a.prev = fp;
  73.     nfp->a.next = na;
  74.     na->a.prev = nfp;
  75.     fp->a.next = nfp;
  76.     
  77.     /* Replace current block on free chain */
  78.     nfp->next_free = fp->next_free;
  79.     nfp->prev_free = fp->prev_free;
  80.     fp->next_free->prev_free = nfp;
  81.     fp->prev_free->next_free = nfp;
  82.   } else {
  83.     /* Allocate the whole block */
  84.     fp->a.type = ARENA_TYPE_USED;
  85.  
  86.     /* Remove from free chain */
  87.     fp->next_free->prev_free = fp->prev_free;
  88.     fp->prev_free->next_free = fp->next_free;
  89.   }
  90.   
  91.   return (void *)(&fp->a + 1);
  92. }
  93.  
  94. void *malloc(size_t size)
  95. {
  96.   struct free_arena_header *fp;
  97.  
  98.   if ( size == 0 )
  99.     return NULL;
  100.  
  101.   /* Add the obligatory arena header, and round up */
  102.   size = (size+2*sizeof(struct arena_header)-1) & ~ARENA_SIZE_MASK;
  103.  
  104.   for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ;
  105.     fp = fp->next_free ) {
  106.     if ( fp->a.size >= size ) {
  107.       /* Found fit -- allocate out of this block */
  108.       return __malloc_from_block(fp, size);
  109.     }
  110.   }
  111.  
  112.   /* Nothing found... need to request a block from the kernel */
  113.   return NULL;            /* No kernel to get stuff from */
  114. }
  115.